package groupon.common.service.impl;

import groupon.commom.model.Navigation;
import groupon.common.service.DataInitializer;
import groupon.common.service.SystemService;
import groupon.common.util.MainNavigationBean;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service(value = "systemService")
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class SystemServiceImpl implements SystemService,
		ApplicationContextAware {

	private ApplicationContext _appContext;
	private List<Navigation> _navigations;

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		_appContext = applicationContext;
	}

	public List<DataInitializer> getDataInitializers(
			String[] externalCtxFilePaths) {
		List<DataInitializer> dataInitializers = new ArrayList<DataInitializer>();
		ApplicationContext extAppContext = (externalCtxFilePaths != null) ? new FileSystemXmlApplicationContext(
				externalCtxFilePaths) : _appContext;
		String[] beanNames = extAppContext
				.getBeanNamesForType(DataInitializer.class);
		for (String beanName : beanNames) {
			dataInitializers.add((DataInitializer) extAppContext
					.getBean(beanName));
		}
		return dataInitializers;
	}

	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void initializeData(String[] externalCtxFilePaths) throws Exception {
		List<DataInitializer> dataInitializers = getDataInitializers(externalCtxFilePaths);
		for (DataInitializer dataInitializer : dataInitializers) {
			dataInitializer.initialize(_appContext);
		}

	}

	public List<Navigation> getNavigations() {
		return _navigations;
	}

	public void setNavigations(List<Navigation> navigation) {
		_navigations = navigation;
	}

	public List<Navigation> getSystemNavigation() {
		String[] beanNames = _appContext
				.getBeanNamesForType(MainNavigationBean.class);
		if (_navigations == null) {
			// Only One Bean is accepted
			for (String beanName : beanNames) {
				MainNavigationBean mainNav = (MainNavigationBean) _appContext
						.getBean(beanName);
				_navigations = mainNav.getListNavigations();
				return _navigations;
			}
		}
		return _navigations;
	}

}